import React, { useEffect, useState, useCallback, useRef } from 'react';
import './index.less';
import { Card, Col, Row, Button } from 'antd';
import G6 from '@antv/g6';

const ComTypes = {
  zhuji: '主机',
  cdn: 'CDN',
  domain: '主域名',
  static: '静态资源',
  api: '接口响应',
  jsError: 'js 报错',
  monitor: '页面监控',
};

const initData = {
  // 点集
  nodes: [
    {
      x: 200,
      y: 200,
      label: '测试',
      text: '\ue680',
    },
  ],
  // 边集
  edges: [],
};
export default function Main(props) {
  const list = [
    { group: '机房', components: [{ type: 'zhuji', title: '主机', icon: 'icon-server' }] },
    {
      group: '网络',
      components: [
        { type: 'cdn', title: 'CDN', icon: 'icon-cdn' },
        { type: 'domain', title: '主域名', icon: 'icon-domain' },
      ],
    },
    {
      group: '前台',
      components: [
        { type: 'static', title: '静态资源', icon: 'icon-js' },
        { type: 'api', title: '接口响应', icon: 'icon-response' },
        { type: 'jsError', title: 'js 报错', icon: 'icon-js-error' },
      ],
    },
    {
      group: '主要页面',
      components: [{ type: 'monitor', title: '页面监控', icon: 'icon-page' }],
    },
  ];

  const registerIconfont = useCallback(() => {
    G6.registerNode('iconfont', {
      draw(cfg, group) {
        debugger;
        const { backgroundConfig: backgroundStyle, style, labelCfg: labelStyle } = cfg;

        if (backgroundStyle) {
          group.addShape('circle', {
            attrs: {
              x: 0,
              y: 0,
              r: cfg.size,
              ...backgroundStyle,
            },
          });
        }

        const keyShape = group.addShape('text', {
          attrs: {
            x: 0,
            y: 0,
            fontFamily: 'iconfont', // 对应css里面的font-family: "iconfont";
            textAlign: 'center',
            textBaseline: 'middle',
            text: cfg.text,
            fontSize: cfg.size,
            ...style,
          },
        });
        const labelY = backgroundStyle ? cfg.size * 2 : cfg.size;

        group.addShape('text', {
          attrs: {
            x: 0,
            y: labelY,
            textAlign: 'center',
            text: cfg.label,
            ...labelStyle.style,
          },
        });
        debugger;
        return keyShape;
      },
    });
  }, []);

  const initG6 = useCallback(() => {
    // 实例化minimap
    const { clientWidth, clientHeight } = containerRef.current;
    const minimap = new G6.Minimap({
      size: [100, 100],

      className: 'minimap',
      type: 'delegate',
    });

    const grid = new G6.Grid();

    registerIconfont();

    const COLOR = '#40a9ff';
    const graph = new G6.Graph({
      container: 'mountNode', // 指定挂载容器
      width: clientWidth, // 图的宽度
      height: clientHeight, // 图的高度
      fitView: true,
      plugins: [minimap, grid],
      defaultNode: {
        backgroundConfig: {
          backgroundType: 'circle',
          fill: COLOR,
          stroke: 'LightSkyBlue',
        },
        shape: 'iconfont',
        size: 20,
        style: {
          fill: '#fff',
        },
        labelCfg: {
          style: {
            fill: COLOR,
            fontSize: 12,
          },
        },
      },
      modes: {
        // 支持的 behavior
        default: ['drag-canvas', 'zoom-canvas', 'click-select', 'drag-node'],
        // 点击选中  节点拖拽
        edit: ['click-select', 'drag-node'],
      },
    });
    graph.data(initData); // 加载数据

    graph.on('canvas:drop', (e) => {
      if (e.originalEvent.dataTransfer) {
        const com = e.originalEvent.dataTransfer.getData('component');
        graph.add('node', {
          x: e.x,
          y: e.y,
          label: ComTypes[com],
          text: '\ue680',
        });
      }
    });

    graph.on('canvas:click', (e) => {
      console.log('canvas:click');
      // graph.setMode('default');
    });
    graph.on('node:click', (e) => {
      console.log('node:click', e.item);
      graph.setItemState(e.item, 'select', true);
      // graph.setMode('edit');
    });

    graph.render(); // 渲染
  }, [registerIconfont]);

  const containerRef = useRef();
  useEffect(() => {
    setTimeout(initG6);
  }, [initG6]);

  const toolBtns = [
    { icon: 'icon-play', title: '播放' },
    { icon: 'icon-reset', title: '重置' },
    { icon: 'icon-zoom-in', title: '缩小' },
    { icon: 'icon-zoom-out', title: '放大' },
    { icon: 'icon-save', title: '保存' },
  ];

  const menuDragger = {
    current: {
      component: null,
    },
    dragstart: (e, component) => {
      containerRef.current.addEventListener('dragenter', menuDragger.dragenter);
      containerRef.current.addEventListener('dragover', menuDragger.dragover);
      containerRef.current.addEventListener('dragleave', menuDragger.dragleave);
      containerRef.current.addEventListener('drop', menuDragger.drop);
      menuDragger.current.component = component;

      e.dataTransfer.setData('component', component);
    },
    dragenter: (e) => {
      e.dataTransfer.dropEffect = 'move';
    },
    dragover: (e) => {
      e.preventDefault();
    },
    dragleave: (e) => {
      e.dataTransfer.dropEffect = 'none';
    },
    dragend: (e) => {
      containerRef.current.removeEventListener('dragenter', menuDragger.dragenter);
      containerRef.current.removeEventListener('dragover', menuDragger.dragover);
      containerRef.current.removeEventListener('dragleave', menuDragger.dragleave);
      containerRef.current.removeEventListener('drop', menuDragger.drop);
      menuDragger.current.component = null;
    },
    drop: (e) => {
      console.log('drop');
    },
  };

  return (
    <div className="monitor-page">
      <h1>全局监控</h1>
      <Row className="main">
        <Col span={5}>
          <Card style={{ height: '100%' }}>
            {list.map((v, i) => (
              <div key={i} className="left-menu">
                <h3>{v.group}</h3>
                {v.components.map((c, idx) => (
                  <Button
                    type="ghost"
                    key={idx}
                    draggable
                    onDragEnd={menuDragger.dragend}
                    onDragStart={(e) => menuDragger.dragstart(e, c.type)}
                    transferdata={c.type}
                  >
                    <i className={`iconfont mr-10 ${c.icon}`}></i>
                    <span>{c.title}</span>
                  </Button>
                ))}
              </div>
            ))}
          </Card>
        </Col>
        <Col span={18} offset={1}>
          <div ref={containerRef} className="container">
            <div className="tool">
              {toolBtns.map((v, i) => (
                <Button type="link" key={i}>
                  <i className={`iconfont ${v.icon}`}></i>
                </Button>
              ))}
            </div>
            <div id="mountNode"></div>
          </div>
        </Col>
      </Row>
    </div>
  );
}
